#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<netinet/in.h>

using namespace std;

#define SERVER_PORT 8888
#define BUFF_LINE 512
#define BUFF_LINE_2 1024
#define SERVER_IP "10.0.16.2"

class UdpCs
{
public:
	UdpCs();
	~UdpCs();

	/*
	client
		UdpCs udp_cs;
		udp_cs.run_sender();
	*/
	void run_sender();
	void preset_sender();
	void start_sender();

	/*
	server
		UdpCs udp_cs;
		udp_cs.run_receiver();
	*/
	void run_receiver();
	void preset_receiver();
	void start_receiver();

private:
	int client_fd;
	int server_fd;
	struct sockaddr_in ser_addr;

	int server_port;
	int buf_send_line;
	string server_ip = "10.0.16.2";	
};

UdpCs::UdpCs()
{}

UdpCs::~UdpCs()
{}

void
UdpCs::run_sender()
{
	preset_sender();
	start_sender();
	close(client_fd);
}

void 
UdpCs::preset_sender()
{
	client_fd = socket(AF_INET, SOCK_DGRAM, 0);
	if(client_fd<0)
	{
		printf("create socket fail!");
		return;	
	}
	
	memset(&ser_addr, 0, sizeof(ser_addr));
	ser_addr.sin_family = AF_INET;
	//ser_addr.sin_addr.s_addr = htonl(SERVER_IP);
	ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	ser_addr.sin_port = htons(SERVER_PORT);
}

void
UdpCs::start_sender()
{
	socklen_t len;
	struct sockaddr_in src;
	struct sockaddr* dst = (struct sockaddr*)&ser_addr;
	while(1)
	{
		char buf[BUFF_LINE] = "TEST UDP MSG!\n";
		len = sizeof(*dst);
		printf("client:%s\n", buf);
		sendto(client_fd, buf, BUFF_LINE, 0, dst, len);
		memset(buf, 0, BUFF_LINE);
		recvfrom(client_fd, buf, BUFF_LINE, 0, (struct sockaddr*)&src, &len);
		printf("server:%s\n", buf);
		sleep(1);
	}
}

void 
UdpCs::run_receiver()
{
	preset_receiver();
	start_receiver();
	close(server_fd);
}

void 
UdpCs::preset_receiver()
{
	server_fd = socket(AF_INET, SOCK_DGRAM, 0);
	if(server_fd<0) 
	{
		printf("create socket fail!");	
		return ;
	}
	memset(&ser_addr, 0, sizeof(ser_addr));
	ser_addr.sin_family=AF_INET;
	ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	ser_addr.sin_port = htons(SERVER_PORT);

	int ret = bind(server_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr));
	if(ret<0)
	{
		printf("socket bind failed!");	
		return ;
	}
}

void 
UdpCs::start_receiver()
{
	char buf[BUFF_LINE_2];
	socklen_t len;

	int count;
	struct sockaddr_in client_addr;

	while(1)
	{
		memset(buf, 0, BUFF_LINE_2);
		len = sizeof(client_addr);
		count = recvfrom(server_fd, buf, BUFF_LINE_2, 0, (struct sockaddr*)&client_addr, &len);
		if(count==-1)
		{
			printf("receive data fail!\n");	
			return ;
		}	
		printf("client:%s\n", buf);
		memset(buf, 0, BUFF_LINE_2);
		sprintf(buf, "I have received %d bytes data!\n", count);
		printf("server:%s\n", buf);
		sendto(server_fd, buf, BUFF_LINE_2, 0, (struct sockaddr*)&client_addr, len);
	}
}

int main(int argc, char **argv)
{

	UdpCs udpCs;

	//开双线程，一个server，一个client
	if(argc!=2)
	{
		printf("wrong arr!\n");
		return -1;
	}

	if(strcmp(argv[1], "server")==0)
	{
		printf("start server\n");
		udpCs.run_receiver();
	}
	else if(strcmp(argv[1], "client")==0)
	{
		printf("start client\n");
		udpCs.run_sender();
	}


	return 0;
}












